/* Copyright (c) 2008, dZettaApart.
   Licensed under the BSD License.
   See COPYING for details. */


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>

#include "memcacheasio_connection.h"
#include "memcacheasio_request.h"

using namespace memcacheasio;

void callback_request ( const boost::system::error_code& err, Request::Ptr ticket )
{ 
	if ( !err )
	{
		std::cout << "Response status : ok" << std::endl;
	}
	else
	{
		std::cout << "Response status : " << err.message() << std::endl;
	}
	std::cout << "Have an answer: ";
	std::cout << ticket->response() << std::endl;
}

void callback_connection_delete ( const boost::system::error_code& err, boost::shared_ptr<Connection> connection )
{ 
	if ( !err )
	{
		std::cout << "Connection status : ok" << std::endl;
	}
	else
	{
		std::cout << "Connection status : " << err.message() << std::endl;
	}
}

void callback_connection_get2 ( const boost::system::error_code& err, boost::shared_ptr<Connection> connection )
{ 
	if ( !err )
	{
		std::cout << "Connection status : ok" << std::endl;
        boost::shared_ptr<Request> request( new Request ( Request::COMMAND_DELETE, "hello_world", "" ) );
        connection->processRequest( request, boost::bind ( &callback_request, _1, _2 ), boost::bind ( &callback_connection_delete, _1, _2 ) );
	}
	else
	{
		std::cout << "Connection status : " << err.message() << std::endl;
	}
}

void callback_connection_set ( const boost::system::error_code& err, boost::shared_ptr<Connection> connection )
{ 
	if ( !err )
	{
		std::cout << "Connection status : ok" << std::endl;
        boost::shared_ptr<Request> request( new Request ( Request::COMMAND_GET, "hello_world", "" ) );
        connection->processRequest( request, boost::bind ( &callback_request, _1, _2 ), boost::bind ( &callback_connection_get2, _1, _2 ) );
	}
	else
	{
		std::cout << "Connection status : " << err.message() << std::endl;
	}
}

void callback_connection_get ( const boost::system::error_code& err, boost::shared_ptr<Connection> connection )
{ 
	if ( !err )
	{
		std::cout << "Connection status : ok" << std::endl;
        boost::shared_ptr<Request> request( new Request ( Request::COMMAND_SET, "hello_world", "HELLO_HELLO" ) );
        connection->processRequest( request, boost::bind ( &callback_request, _1, _2 ), boost::bind ( &callback_connection_set, _1, _2 ) );
	}
	else
	{
		std::cout << "Connection status : " << err.message() << std::endl;
	}
}

void callback_connected ( const boost::system::error_code& err, boost::shared_ptr<Connection> connection )
{ 
	if ( !err )
	{
		std::cout << "Connected status : ok" << std::endl;
        boost::shared_ptr<Request> request( new Request ( Request::COMMAND_GET, "hello_world", "" ) );
        connection->processRequest( request, boost::bind ( &callback_request, _1, _2 ), boost::bind ( &callback_connection_get, _1, _2 ) );
	}
	else
	{
		std::cout << "Connected status : " << err.message() << std::endl;
	}
}

int main ( /*int argc, char *argv[]*/ )
{
	try
	{
		std::cout << "Hello, world!" << std::endl;

        std::string host = "localhost";
//		std::string host = "127.0.0.1";
        std::string port = "11211";

        boost::asio::io_service  io_service;

		boost::shared_ptr<Connection> connection ( new Connection( io_service ) );

        connection->connect( host, port, boost::bind ( &callback_connected, _1, connection ));

        boost::shared_ptr<boost::thread> thread ( new boost::thread ( boost::bind ( &boost::asio::io_service::run, &io_service ) ) );

        thread->join();
/*
		memc.execute ( boost::shared_ptr<Request> ( new Request ( Request::COMMAND_GET, "hello_world", "", boost::bind ( &_callback_get, _1 ) ) ) );

		memc.execute ( boost::shared_ptr<Request> ( new Request ( Request::COMMAND_DELETE, "hello_world", "", boost::bind ( &_callback_get, _1 ) ) ) );
*/
	}
	catch ( std::exception& e )
	{
        std::cout << "Exception :" << e.what() << std::endl;
	}

	return EXIT_SUCCESS;
}
